﻿<cfsilent>
	<cfsetting requesttimeout="90" />
	<cfscript>

		jsonAdvice = getProperty("serviceFactory").getBean("jsonAdvice");
		sessionAdvice = getProperty("serviceFactory").getBean("sessionAdvice");
		datetimeAdvice = getProperty("serviceFactory").getBean("datetimeAdvice");

		chooseProp = getProperty("serviceFactory").getBean("choosePropertyAdvice");
		taskProp = getProperty("serviceFactory").getBean("taskPropertyAdvice");
		turnProp = getProperty("serviceFactory").getBean("turnPropertyAdvice");
		studentPropAdvice = getProperty("serviceFactory").getBean("studentPropertyAdvice");
		
		sequenceStudentCourse = getProperty("serviceFactory").getBean("sequenceStudentCourse");

		termId = event.getArg("TermID");
		courseId = event.getArg("CID");
		courseIdx = event.getArg("CIDX");
		taskType = event.getArg("TT");
		taskId = event.getArg("TSK");

		coursePropId = event.getArg("CP");

		secureTicket = event.getArg("ST");
		
		turnId = event.getArg("CT");

		/* 学籍相关信息 */
		studentId = sessionAdvice.getAutherUserID();
		//studentClassId = sessionAdvice.getUserProp("studentClass");
		studentSubjectId = sessionAdvice.getUserProp("studentSubject");
		//studentDirId = sessionAdvice.getUserProp("studentSubDir");
		studentGrade = sessionAdvice.getUserProp("studentGrade");
		studentDepartment = sessionAdvice.getUserProp("studentDepartment");
		studentProps = sessionAdvice.getUserProp("studentProps");
		
		studentPropAdvice.parseProperty( studentProps );

		chooserSecure = false;
		chooserAllowed = false;

		/* 回执信息 */
		response = structNew();
		structInsert(response, "success", false, true);


		/* 首先做安全检查 */
		try {
			stringOrignal = decrypt(secureTicket, taskId, "PBEWithMD5AndDES", "Hex");
			stringTest = courseId & courseIdx & termId & taskType;
			
			if ( stringOrignal eq stringTest ) {
				chooserSecure = true;
			}
		}
		catch(any excpt) {
		}
		
		if ( chooserSecure ) {

			/* 检查选课轮次 */
			if ( len(turnId) ) {
 
				sql="SELECT a.date_start,a.date_end,
					    a.time_start,a.time_end,
					    a.grade_allowed,a.institute_allowed,
					    a.subject_allowed,a.turn_prop 
					 FROM t_choose_turn a 
					 WHERE a.ct = :turnId ";
				queryObj = new Query( datasource=application.dnsSlave ); 
				queryObj.addParam( name="turnId", value=turnId, cfsqltype="cf_sql_char" );
				rs_turn = queryObj.execute( sql=sql ).getResult();		
				if (rs_turn.recordCount GT 0) {
				
					today = datetimeAdvice.getCurrentDateString();
					currentTime = TimeFormat(now(), "HHMM");
				
					if ( rs_turn.date_start lte today and today lte rs_turn.date_end ) {
						if ( rs_turn.time_start lte currentTime and currentTime lte rs_turn.time_end ) {
							if ( rs_turn.grade_allowed eq "ALL" or listFind(rs_turn.grade_allowed, studentGrade, ",") ) {
								if ( rs_turn.institute_allowed eq "ALL" or listFind(rs_turn.institute_allowed, studentDepartment, ",") or (rs_turn.subject_allowed neq '-' and listFind(rs_turn.subject_allowed, studentSubjectId)) ) {
									/* 是否开放提前毕业选课 */
									turnProp.parseProperty(rs_turn.turn_prop);
									if ( turnProp.getEarlyGraduate() and studentPropAdvice.getEarlyGraduate() ) {
										chooserAllowed = true;
									}
								}
							}
						}
					}
				}
			}
			
			if ( chooserAllowed ) {
				
				transaction {
					
					/* 添加选课记录 */
 		
					switch(taskType){
						case 'C':
							sql = "	SELECT 
									 tsk.task_limite,tsk.task_chooesd 
									FROM 
									 t_common_task tsk  
									WHERE 
									  tsk.tsk_id = :taskId ";
							break;
						case 'P':
							sql = "	SELECT 
									 tsk.task_limite,tsk.task_chooesd 
									FROM 
									 t_task tsk  
									WHERE 
									  tsk.tsk_id = :taskId ";
							break;
						case 'R':
							sql = "	SELECT 
									 tsk.task_limite,tsk.task_chooesd 
									FROM 
									 t_reopen_task tsk  
									WHERE 
									  tsk.tsk_id = :taskId ";
							break;
						case 'T':
							sql = "	SELECT 
									 tsk.task_limite,tsk.task_chooesd 
									FROM 
									 t_sport_task tsk  
									WHERE 
									  tsk.tsk_id = :taskId ";
							break;
					}

				queryObj = new Query(datasource = application.dnsMaster);
				queryObj.addParam(name ="taskId", value=taskId, cfsqltype="cf_sql_varchar");
				rs_task = queryObj.execute(sql = sql).getResult();

					/* 检查教学班是否还有空席位 */
					if ( rs_task.task_limite gt rs_task.task_chooesd ) {
						
		 		        newSize = rs_task.task_chooesd + 1;
					 
						switch(taskType){
							case 'C':
								sql = "	UPDATE t_common_task tsk 
										SET tsk.task_chooesd = :newSize 
										WHERE tsk.tsk_id = :taskId ";
								break;
							case 'P':
								sql = "	UPDATE t_task tsk 
										SET tsk.task_chooesd = :newSize 
										WHERE tsk.tsk_id = :taskId ";
								break;
							case 'R':
								sql = "	UPDATE t_reopen_task tsk 
										SET tsk.task_chooesd = :newSize 
										WHERE tsk.tsk_id = :taskId ";
								break;
							case 'T':
								sql = "	UPDATE t_sport_task tsk 
										SET tsk.task_chooesd = :newSize 
										WHERE tsk.tsk_id = :taskId ";
								break;
						}
						updateObj = new Query(datasource = application.dnsMaster);
						updateObj.addParam(name ="newSize", value=newSize, cfsqltype="cf_sql_integer");
						updateObj.addParam(name ="taskId", value=taskId, cfsqltype="cf_sql_varchar");
				        updateObj.execute(sql = sql); 
					 
						/* required Student, required Course, required Term, required string TaskType */
 
						sequenceStudentCourse.setStudentID(studentId);
						sequenceStudentCourse.setCourseId(courseId);
						sequenceStudentCourse.setTermID(termId);
						sequenceStudentCourse.setTaskType(taskType);
						chooserId = sequenceStudentCourse.getID();
				
						timeStamp = datetimeAdvice.getCurrentDatetimeString();
					
 
						sql = "	SELECT a.choose_prop,a.task_type,
									   a.task_id 
								FROM t_student_course a 
								WHERE a.scc_id = :chooserId ";
						queryObj = new Query(datasource = application.dnsMaster);
						queryObj.addParam(name ="chooserId", value=chooserId, cfsqltype="cf_sql_varchar");
						rs_studentCourse = queryObj.execute(sql = sql).getResult();
						
						
						if ( rs_studentCourse.recordCount eq 0 ) {
							
							prop = chooseProp.init();
							
							/* 预置课表是否锁定 */
							prop.setLocked(false);
							/* 缴费状态设置 */
							prop.setPrePaid( true ); /* 是否从预交学费扣除 */
							prop.setPaid( true ); /* 是否已收费 */

							/* 没有选课记录 */
				  				
							sql = "INSERT INTO t_student_course
											  (scc_id,
											   stu_id,
											   cid,
											   term_id,
											   prop_id,
											   task_type,
											   cidx,
											   task_id,
											   st,
											   retaking,
											   ct,
											   choose_time,
											   choose_prop,
											   charge_time)
											VALUES
											 ( :chooserId ,
											   :studentId ,
											   :courseId ,
											   :termId ,
											   :propId ,
											   :taskType ,
											   :cidx ,
											   :taskId ,
											   :studyType ,
											   :retaking ,
											   :turnId ,
											   :chooseTime ,
											   :chooseProp ,
											   :chargeTime )";

									queryObj = new Query(datasource = application.dnsMaster);
									queryObj.addParam(name="chooserId", value=chooserId, cfsqltype="cf_sql_varchar");
									queryObj.addParam(name="studentId", value=studentId, cfsqltype="cf_sql_varchar");
									queryObj.addParam(name="courseId", value=courseId, cfsqltype="cf_sql_varchar");
									queryObj.addParam(name="termId", value=termId, cfsqltype="cf_sql_char");
									queryObj.addParam(name="propId", value=coursePropId, cfsqltype="cf_sql_char");
									queryObj.addParam(name="taskType", value=taskType, cfsqltype="cf_sql_char");
									queryObj.addParam(name="cidx", value=courseIdx, cfsqltype="cf_sql_char");
									queryObj.addParam(name="taskId", value=taskId, cfsqltype="cf_sql_varchar");
									queryObj.addParam(name="studyType", value='E', cfsqltype="cf_sql_char");
									queryObj.addParam(name="retaking", value='0', cfsqltype="cf_sql_char");
									queryObj.addParam(name="turnId", value=turnId, cfsqltype="cf_sql_varchar");
									queryObj.addParam(name="chooseTime", value=timeStamp, cfsqltype="cf_sql_char");
									queryObj.addParam(name="chooseProp", value=prop.stringProperty(), cfsqltype="cf_sql_varchar");
									queryObj.addParam(name="chargeTime", value=timeStamp, cfsqltype="cf_sql_char");
									queryObj.execute(sql = sql);											
						}
						else {

							/* 更新选课记录 */
							prop = chooseProp.init();
							prop.parseProperty( rs_studentCourse.choose_prop );
							/* 缴费状态设置 */
							prop.setPrePaid( true ); /* 是否从预交学费扣除 */
							prop.setPaid( true ); /* 是否已收费 */

							//改选以后，将原来的教学任务人数实际人数减去1
			 	
							switch(rs_studentCourse.task_type){
							case 'C':
								sql = "	UPDATE t_common_task tsk 
										SET tsk.task_chooesd = tsk.task_chooesd - 1 
										WHERE tsk.tsk_id = :taskId ";
								updateObj = new Query(datasource = application.dnsMaster);								
								updateObj.addParam(name ="taskId", value=rs_studentCourse.task_id, cfsqltype="cf_sql_varchar");
								updateObj.execute(sql = sql);	
								break;
							case 'P':								
								sql = "	UPDATE t_task tsk 
										SET tsk.task_chooesd = tsk.task_chooesd - 1 
										WHERE tsk.tsk_id = :taskId ";
								updateObj = new Query(datasource = application.dnsMaster);
								updateObj.addParam(name ="taskId", value=rs_studentCourse.task_id, cfsqltype="cf_sql_varchar");
								updateObj.execute(sql = sql);	
								break;
							case 'R':
								sql = "	UPDATE t_reopen_task tsk 
										SET tsk.task_chooesd = tsk.task_chooesd - 1 
										WHERE tsk.tsk_id = :taskId ";
								updateObj = new Query(datasource = application.dnsMaster);
								updateObj.addParam(name ="taskId", value=rs_studentCourse.task_id, cfsqltype="cf_sql_varchar");
								updateObj.execute(sql = sql);	
								break;
							case 'T':
								sql = "	UPDATE t_sport_task tsk 
										SET tsk.task_chooesd = tsk.task_chooesd - 1 
										WHERE tsk.tsk_id = :taskId ";
								updateObj = new Query(datasource = application.dnsMaster);
								updateObj.addParam(name ="taskId", value=rs_studentCourse.task_id, cfsqltype="cf_sql_varchar");
								updateObj.execute(sql = sql);	
								break;
							}

							/*Unique: STU_ID, CID, TERM_ID, TASK_TYPE*/
						 
							sql = "	UPDATE t_student_course a
									SET a.choose_prop = :chooseProp ,
										a.cidx = :courseIdx ,
										a.task_id = :taskId ,
										a.st = :studyType ,
										a.retaking = :retaking ,
										a.choose_time = :timeStamp ,
										a.charge_time = :timeStamp ,
										a.ct = :turnId ,
										a.prop_id = :coursePropId 
									WHERE
										 a.scc_id = :chooserId";
							updateObj = new Query(datasource = application.dnsMaster);
							updateObj.addParam(name ="courseIdx", value=courseIdx, cfsqltype="cf_sql_varchar");
							updateObj.addParam(name ="taskId", value=taskId, cfsqltype="cf_sql_char");
							updateObj.addParam(name ="studyType", value="E", cfsqltype="cf_sql_char");
							updateObj.addParam(name ="retaking", value="0", cfsqltype="cf_sql_char");
							updateObj.addParam(name ="timeStamp", value=timeStamp, cfsqltype="cf_sql_char");							
							updateObj.addParam(name ="chooseProp", value=prop.stringProperty(), cfsqltype="cf_sql_char");							
							updateObj.addParam(name ="coursePropId", value=coursePropId, cfsqltype="cf_sql_char");
							updateObj.addParam(name ="turnId", value=turnId, cfsqltype="cf_sql_varchar");							
							updateObj.addParam(name="chooserId", value=chooserId, cfsqltype="cf_sql_varchar");
							updateObj.execute(sql = sql);
						}
						 
						structInsert(response, "success", true, true);
						
					}
					else {
						structInsert(response, "reason", "选课人数已满", true);
					}
					
				}
			}
			else {
				structInsert(response, "reason", "现在不是选课时段", true);
			}
		}
		else {
			structInsert(response, "reason", "参数错误", true);
		}

	</cfscript>
</cfsilent><cfoutput>#jsonAdvice.encode(data:response, stringNumbers:true)#</cfoutput>